package cn.com.pajx.pajx_visitor_v3.utils;

import android.annotation.SuppressLint;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;

import androidx.annotation.NonNull;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

import cn.com.pajx.pajx_visitor_v3.BaseApp;

/**
 * Created by ruancw on 2023/01/05
 * Describe ：媒体文件工具
 */
public class MediaStoreUtil {

    private static final String JPG = ".jpg";
    private final String PNG = ".png";
    public static final String FACE_GATHER_DIR = "face_gather";
    public static final String FACE_RECOGNITION_DIR = "face_recognition";

    public static final String BASE_FOLDER = Environment.DIRECTORY_PICTURES + File.separator + "PAJX_VISITOR";
    public static final String BASE_DOWNLOAD_FOLDER = Environment.DIRECTORY_DOWNLOADS + File.separator + "PAJX_VISITOR";


    public static String getBaseMediaStore(Context c) {
        File dataFile = Environment.getExternalStoragePublicDirectory(BASE_FOLDER).getAbsoluteFile();
        File mediaStorageDir = new File(dataFile.getAbsolutePath());
        if (!mediaStorageDir.exists()) {
            mediaStorageDir.mkdirs();
        }
        return mediaStorageDir.getAbsolutePath();
    }

    /**
     * *在SD卡上创建目录
     *
     * @param dirName 文件夹名称
     */
    public File createDir(Context context, String dirName) {
        File dir = new File(getBaseMediaStore(context) + dirName);
        dir.mkdir();
        return dir;
    }

    /**
     * 判断SD卡上的文件夹是否存在
     */
    public boolean isFileExist(Context context, String fileName) {
        File file = new File(getBaseMediaStore(context) + fileName);
        return file.exists();
    }

    /**
     * 获取当前文件夹下所有文件的名字
     *
     * @param fileDir 查询的文件夹名字（如学校编号：00000）
     * @return 子文件名称集合
     */
    public static List<String> loadAllFileNames(String fileDir) {
        // 得到该路径文件夹下所有的文件
        File[] files = loadMediaStorageFiles(fileDir);
        if (files == null) {
            return null;
        }
        List<String> fileNames = new ArrayList<>();
        for (File file : files) {
            fileNames.add(file.getName());
        }
        //排序
        Collections.sort(fileNames, String::compareToIgnoreCase);
        return fileNames;
    }

    /**
     * 建立保存头像的路径及名称
     */

    public static File saveOutputMediaFile(String fileDir, String mImageName) {
        File mediaStorageDir;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            File dataFile = Objects.requireNonNull(BaseApp.getInstance().getExternalFilesDir(null)).getAbsoluteFile();
            mediaStorageDir = new File(dataFile.getAbsolutePath() + BASE_FOLDER + fileDir);
        } else {
            mediaStorageDir = new File(Environment.getExternalStorageDirectory()
                    + BASE_FOLDER + fileDir);
        }

        if (!mediaStorageDir.exists()) {
            if (!mediaStorageDir.mkdirs()) {
                return null;
            } else mediaStorageDir.mkdirs();
        }
        File mediaFile;
        // 设置图片名字
        mediaFile = new File(mediaStorageDir.getPath() + File.separator + mImageName + JPG);
        return mediaFile;
    }

    /**
     * 获取文件夹下的所有图片路径
     *
     * @param fileDir 文件夹
     * @return 文件路径
     */
    public static File[] loadImageFiles(String fileDir) {

        File mediaStorageDir;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            File dataFile = Objects.requireNonNull(BaseApp.getInstance().getExternalFilesDir(null)).getAbsoluteFile();
            mediaStorageDir = new File(dataFile.getAbsolutePath() + BASE_FOLDER + fileDir);
        } else {
            mediaStorageDir = new File(Environment.getExternalStorageDirectory()
                    + BASE_FOLDER + fileDir);
        }

        File[] listFiles = new File[0];
        if (!mediaStorageDir.exists()) {
            if (!mediaStorageDir.mkdirs()) {
                return null;
            }
        } else {
            listFiles = mediaStorageDir.listFiles();
        }
        return listFiles;
    }

    /**
     * 检查媒体文件是否存在
     *
     * @param fileDir  子文件夹名称
     * @param fileName 文件名
     * @return 文件
     */
    public static File checkMediaFileIsExists(String fileDir, String fileName) {
        File mediaStorageDir = Environment.getExternalStoragePublicDirectory(BASE_FOLDER + File.separator + fileDir).getAbsoluteFile();
        if (!mediaStorageDir.exists()) {
            if (!mediaStorageDir.mkdirs()) {
                return null;
            } else mediaStorageDir.mkdirs();
        }
        File mediaFile;
        // 设置图片名字
        mediaFile = new File(mediaStorageDir.getPath() + File.separator + fileName + ".jpg");
        return mediaFile;
    }

    /**
     * MediaStorage中获取图片文件集合
     *
     * @param fileDir 子文件夹
     * @return 文件集合
     */
    public static File[] loadMediaStorageFiles(String fileDir) {
        File mediaStorageDir = Environment.getExternalStoragePublicDirectory(BASE_FOLDER + File.separator + fileDir).getAbsoluteFile();
        LogUtils.e("mediaStorageDir=" + mediaStorageDir.getAbsolutePath());
        File[] listFiles = new File[0];
        if (!mediaStorageDir.exists()) {
            if (!mediaStorageDir.mkdirs()) {
                return null;
            }
        } else {
            listFiles = mediaStorageDir.listFiles();
        }
        return listFiles;
    }

    /**
     * 以流的形式保存拍照的图片到指定文件夹
     *
     * @param bitmap     要保存的图片
     * @param fileDir    文件夹名称
     * @param mImageName 要保存的文件名称
     */
    public static void saveBitmap2SD(Bitmap bitmap, String fileDir, String mImageName) {
        FileOutputStream fos = null;
        File bitmapFile = saveOutputMediaFile(fileDir, mImageName);
        if (bitmapFile == null) {
            return;
        }
        try {
            fos = new FileOutputStream(bitmapFile);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                assert fos != null;
                fos.flush();
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 从sd卡获取图片资源路径
     *
     * @param fileDir 文件夹名称
     * @return 路径列表
     */
    public static List<String> loadFolderFilePaths(String fileDir) {
        // 图片路径存储列表
        List<String> imagePathList = new ArrayList<>();
        // 得到该路径文件夹下所有的文件
        File[] files = loadMediaStorageFiles(fileDir);
        // 将所有的文件存入ArrayList中,并过滤所有图片格式的文件
        assert files != null;
        for (File file : files) {
            if (checkIsImageFile(file.getPath())) {
                imagePathList.add(file.getPath());
            }
        }
        // 返回得到的图片路径列表
        return imagePathList;
    }

    /**
     * 检查扩展名，得到图片格式的文件
     *
     * @param fName 文件名
     * @return 布尔值
     */
    @SuppressLint("DefaultLocale")
    private static boolean checkIsImageFile(String fName) {
        boolean isImageFile;
        // 获取扩展名
        String FileEnd = fName.substring(fName.lastIndexOf(".") + 1).toLowerCase();
        isImageFile = FileEnd.equals("jpg") || FileEnd.equals("png") || FileEnd.equals("gif")
                || FileEnd.equals("jpeg") || FileEnd.equals("bmp");
        return isImageFile;
    }

    /**
     * 判断文件是否存在
     *
     * @param strFile 文件名
     * @return 布尔类型
     */
    public static boolean fileIsExists(String strFile) {
        try {
            File f = new File(strFile);
            if (!f.exists()) {
                return false;
            }

        } catch (Exception e) {
            return false;
        }

        return true;
    }

    /**
     * 获取选中上传图片files
     *
     * @param listImagePaths 选中图片的路径集合
     * @return 返回图片文件数组
     */
    public static File[] getUploadImageFiles(List<String> listImagePaths) {
        File[] files = new File[]{};
        if (listImagePaths.size() != 0) {
            for (int i = 0; i < listImagePaths.size(); i++) {
                files[i] = new File(listImagePaths.get(i));
            }
        }
        return files;
    }

    /**
     * 保存Bitmap到媒体库公共目录如：Pictures等
     *
     * @param context  上下文对象
     * @param fileDir  文件夹（子文件夹）
     * @param fileName 文件名（带后缀如：test.jpg）
     * @param bitmap   要保存的bitmap对象
     */
    public static void saveBitmapToMediaStore(Context context, String fileDir, String fileName, Bitmap bitmap) {
        ContentValues contentValues = new ContentValues();
        contentValues.put(MediaStore.Images.ImageColumns.DISPLAY_NAME, fileName + JPG);
        contentValues.put(MediaStore.Images.Media.TITLE, "PAJX");
        contentValues.put(MediaStore.Images.Media.DESCRIPTION, fileDir);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            //Android 10.0 RELATIVE_PATH 字段表示相对路径
            contentValues.put(MediaStore.Images.ImageColumns.RELATIVE_PATH, BASE_FOLDER + File.separator + fileDir);
        } else {
            String dstPath = Environment.getExternalStorageDirectory().getPath() + File.separator
                    + BASE_FOLDER + File.separator + fileDir + File.separator + fileName + JPG;
            File file = new File(dstPath);
            //创建文件夹目录
            if (!Objects.requireNonNull(file.getParentFile()).exists()) {
                file.getParentFile().mkdirs();
            }
            //DATA字段在Android 10.0 之后已经废弃
            contentValues.put(MediaStore.Images.ImageColumns.DATA, dstPath);
        }
        //已存在删除
        String path = checkImageFromMediaStore(context, fileDir, fileName);
        if (!TextUtils.isEmpty(path)) {
            deleteImageFromMediaStore(context, fileDir, fileName);
        }
        //插入相册
        Uri uri = Objects.requireNonNull(context).getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
        if (uri == null) return;
        writeBitmapToFile(context, bitmap, uri);

    }

    /**
     * 下载文件到下载目录
     *
     * @param context     context
     * @param inputStream 输入流
     * @param mimeType    文件类型
     * @param fileName    文件名称
     */
    public static void saveFileToMediaStore(Context context, InputStream inputStream, String mimeType, String fileName) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {//Android  >= 10
            Uri externalDownloadUri = MediaStore.Downloads.EXTERNAL_CONTENT_URI;
            ContentValues values = new ContentValues();
            values.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName);
            values.put(MediaStore.MediaColumns.MIME_TYPE, mimeType);

            Uri resultUri = context.getContentResolver().insert(externalDownloadUri, values);
            if (resultUri == null) {
                LogUtils.e("下载失败");
            }
            OutputStream out;
            byte[] buffer = new byte[2048];
            int len;
            try {
                out = context.getContentResolver().openOutputStream(resultUri);
                while ((len = inputStream.read(buffer)) != -1) {
                    Objects.requireNonNull(out).write(buffer, 0, len);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            byte[] buf = new byte[2048];
            int len;
            FileOutputStream fos = null;
            try {
                File dir = new File(BASE_DOWNLOAD_FOLDER);
                if (!dir.exists()) {
                    dir.mkdirs();
                }
                File file = new File(dir, fileName);
                fos = new FileOutputStream(file);
                while ((len = inputStream.read(buf)) != -1) {
                    fos.write(buf, 0, len);
                }
                fos.flush();
                //如果下载文件成功，第一个参数为文件的绝对路径
                LogUtils.e("file.getAbsolutePath()=" + file.getAbsolutePath());
            } catch (IOException e) {
                LogUtils.e("IOException=" + e.getMessage());
            } finally {
                try {
                    if (inputStream != null) inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    if (fos != null) fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }

    /**
     * 将Bitmap保存为文件
     *
     * @param context 上下文
     * @param bitmap  bitmap对象
     * @param uri     插入相册的Uri
     */
    private static void writeBitmapToFile(Context context, Bitmap bitmap, Uri uri) {
        //打开了输出流,保存图片
        OutputStream outputStream = null;
        try {
            outputStream = context.getContentResolver().openOutputStream(uri);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.flush();
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }

    /**
     * Uri转File
     *
     * @param context 上下文
     * @param uri     文件的Uri
     * @return 文件
     */
    private static File uriToFile(Context context, Uri uri) {
        String imagePath;
        String[] projection = {MediaStore.Images.Media.DATA};
        @SuppressLint("Recycle")
        Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null);
        if (cursor == null) {
            imagePath = uri.getPath();
        } else {
            int cursorIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            imagePath = cursor.getString(cursorIndex);

        }
        assert cursor != null;
        cursor.close();
        return new File(imagePath);

    }

    /**
     * 保存Bitmap到媒体库公共目录
     * 如Pictures/Download等
     *
     * @param context  上下文对象
     * @param fileDir  子文件夹名称
     * @param fileName 文件名（带后缀）
     * @param bitmap   要保存的Bitmap
     */
    public static void saveBitmapImage(Context context, String fileDir, String fileName, Bitmap bitmap) {

        ContentValues contentValues = new ContentValues();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {//10 及以上
            contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, BASE_FOLDER + File.separator + fileDir);
            contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/png");
            contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, fileName + JPG);
            contentValues.put(MediaStore.Images.Media.TITLE, "PAJX");
            contentValues.put(MediaStore.Images.Media.DESCRIPTION, fileDir);
            //返回出一个URI
            Uri insert = Objects.requireNonNull(context).getContentResolver()
                    .insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                            contentValues);
            if (insert == null) return;
            //这个打开了输出流  直接保存图片就好了
            OutputStream outputStream = null;
            try {
                outputStream = context.getContentResolver().openOutputStream(insert);
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } finally {
                if (outputStream != null) {
                    try {
                        outputStream.flush();
                        outputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            }

        } else {
            saveBitmap(context, fileDir, fileName, bitmap);
        }

    }

    /**
     * @param context 上下文
     * @param fileDir 文件夹
     * @param bitName 文件名
     * @param bitmap  文件Bitmap对象
     */
    public static void saveBitmap(Context context, String fileDir, String bitName, Bitmap bitmap) {
        String fileName = Environment.getExternalStorageDirectory().getPath() + File.separator + BASE_FOLDER + "/" + fileDir + "/" + bitName;
        File file = new File(fileName);
        //创建文件夹目录
        if (!Objects.requireNonNull(file.getParentFile()).exists()) {
            if (!file.getParentFile().mkdirs()) {
                LogUtils.e("createFile: 目录创建失败！！！");
                return;
            }
        }
        if (file.exists()) {
            file.delete();
        }
        LogUtils.e("filePath=" + file.getAbsolutePath());
        FileOutputStream out;
        try {
            out = new FileOutputStream(file);
            // 格式为 JPEG，照相机拍出的图片为JPEG格式的，PNG格式的不能显示在相册中
            if (bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out)) {
                out.flush();
                out.close();
                // 插入图库
                MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), bitName, fileDir);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 发送广播，通知刷新图库的显示
        context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse(file.getParent())));
    }

    /**
     * 媒体库读取文件
     *
     * @param context 上下文对象
     * @param fileDir 查询的目录(子文件目录)
     */
    public static List<String> readImageFromMediaStore(Context context, String fileDir) {
        List<String> imagePaths = new ArrayList<>();
        ContentResolver contentResolver = context.getContentResolver();
        Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        String selection = MediaStore.Images.Media.DATA + " like ? ";
        String[] selectionArgs = new String[]{"%" + fileDir + "%"};
        @SuppressLint("Recycle")
        Cursor cursor = contentResolver.query(contentUri, null, selection, selectionArgs, null);
        LogUtils.e("cursor=" + (cursor != null));
        assert cursor != null;
        LogUtils.e("moveToNext=" + cursor.moveToNext());
        LogUtils.e("cursor_count=" + cursor.getCount());
        try {
            do {
                //取出路径
                @SuppressLint("Range")
                String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA));
                LogUtils.e("path=" + path);
                imagePaths.add(path);
                Uri queryUri = ContentUris.withAppendedId(contentUri, cursor.getLong(0));
                LogUtils.e("queryUri=" + queryUri.toString());
            } while (cursor.moveToNext());
        } catch (Exception e) {
            LogUtils.e(e.getLocalizedMessage());
        }
        cursor.close();
        LogUtils.e("imagePaths=" + imagePaths.size());
        return imagePaths;
    }

    /**
     * 媒体库读取文件
     *
     * @param context  上下文
     * @param fileName 检索的文件名（带后缀，如：test.jpg）
     */
    public static void deleteExitsFromMediaStore(Context context, String fileName) {
        Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        String selection = MediaStore.Images.Media.DISPLAY_NAME + "=?";
        String[] args = new String[]{fileName + JPG};
        Cursor cursor = context.getContentResolver().query(contentUri, null, selection, args, null);
        try {
            while (true) {
                assert cursor != null;
                if (!cursor.moveToNext()) break;
                //取出路径
                @SuppressLint("Range")
                String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA));
                LogUtils.e("path=" + path);
                Uri queryUri = ContentUris.withAppendedId(contentUri, cursor.getLong(0));
                LogUtils.e("queryUri=" + queryUri);
                File file = new File(path);
                file.delete();
            }
        } catch (Exception e) {
            LogUtils.e(e.getLocalizedMessage());
        }
        cursor.close();
    }

    /**
     * 媒体库读取文件
     *
     * @param context  上下文
     * @param fileName 检索的文件名（带后缀，如：test.jpg）
     */
    public static String checkImageFromMediaStore(Context context, String fileDir, String fileName) {
        Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        String selection = MediaStore.Images.Media.DISPLAY_NAME + "=?";
        String[] args = new String[]{fileName + JPG};
        Cursor cursor = context.getContentResolver().query(contentUri, null, selection, args, null);
        if (cursor == null) return "";
        try {
            while (cursor.moveToNext()) {
                //取出路径
                @SuppressLint("Range")
                String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA));
                LogUtils.e("path=" + path);
                Uri queryUri = ContentUris.withAppendedId(contentUri, cursor.getLong(0));
                LogUtils.e("queryUri=" + queryUri.toString());
                return path;
            }
        } catch (Exception e) {
            LogUtils.e(e.getLocalizedMessage());
        }
        cursor.close();
        return "";
    }

    /**
     * 删除媒体库文件
     *
     * @param context  上下文对象
     * @param fileName 文件名（带后缀，如：test.jpg）
     */
    public static void deleteImageFromMediaStore(Context context, String fileDir, String fileName) {
        Uri CONTENT_URI = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        String selection = MediaStore.Images.Media.DISPLAY_NAME + "=?";
        String[] arguments = new String[]{fileName + JPG};
        int delete = context.getContentResolver().delete(CONTENT_URI, selection, arguments);
        LogUtils.e("deleteFile: " + delete);
        //发生异常返回-1
        if (delete > -1) {
            LogUtils.e("delete : " + delete);
        } else {
            LogUtils.e("deleteFile: 失败 " + delete);
        }
    }

    @NonNull
    public static File loadDirFile(String fileDir) {
        File mediaStorageDir = Environment.getExternalStoragePublicDirectory(BASE_FOLDER + File.separator + fileDir).getAbsoluteFile();
        if (!mediaStorageDir.exists()) {
            mediaStorageDir.mkdirs();
        }
        return mediaStorageDir;
    }

    /**
     * * 清除本应用内部缓存(/data/data/com.xxx.xxx/cache) * *
     *
     * @param context context
     */
    public static void cleanAppCache(Context context) {
        deleteFilesByDirectory(context.getCacheDir());
    }


    /**
     * * 删除方法 这里只会删除某个文件夹下的文件，如果传入的directory是个文件，将不做处理 * *
     *
     * @param dir 文件夹
     */
    private static boolean deleteFilesByDirectory(File dir) {
        if (dir != null && dir.isDirectory()) {
            String[] children = dir.list();
            for (String child : children) {
                boolean success = deleteFilesByDirectory(new File(dir, child));
                if (!success) {
                    return false;
                }
            }
        }
        return dir.delete();
    }

}
